using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Principal;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using System.IO;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using stdole;

namespace BJMetro
{
    // ===================================================================================
    // 主窗体类，处理地铁路径分析的核心逻辑
    // ===================================================================================
    public partial class Form1 : Form
    {
        private IMapControl4 _mapControl; // 地图控件
        private int _layerCount = 0; // 图层数量监控
        private MetroGraph _currentMetroGraph; // 缓存的地铁网络图

        public Form1()
        {
            InitializeComponent();
            InitializeUserInterface();
        }

        /// <summary>
        /// 初始化用户界面和基本设置
        /// </summary>
        private void InitializeUserInterface()
        {
            // 获取当前用户名
            string fullUserName = WindowsIdentity.GetCurrent().Name;
            string userName;
            int backslashIndex = fullUserName.LastIndexOf('\\');
            if (backslashIndex >= 0)
            {
                userName = fullUserName.Substring(backslashIndex + 1);
            }
            else
            {
                userName = fullUserName;
            }

            // 初始化控件状态
            shortestPast.Enabled = false;

            // 添加城市选项
            metroChoice.Items.Add("北京市");
            metroChoice.Items.Add("天津市");
            metroChoice.Items.Add("南通市");
            metroChoice.Items.Add("青岛市");
            metroChoice.Items.Add("唐山市");

            // 设置结果文本框
            Result.ScrollBars = ScrollBars.Vertical;
            Result.Enabled = true;
            Result.ReadOnly = true;

            // 设置默认显示文本
            MessageBox.Show($"用户{userName},欢迎使用地铁换乘助手", "欢迎", MessageBoxButtons.OK);
            metroChoice.Text = "请选择分析城市";
            cboStart.Text = "请选择起始点";
            cboDeter.Text = "请选择结束点";
            Result.Text = "换乘路线分析：";

            // 初始化地图控件
            if (!DesignMode)
            {
                _mapControl = (IMapControl4)axMapControl1.Object;
                if (_mapControl.Map != null)
                {
                    _layerCount = _mapControl.Map.LayerCount;
                }
                axMapControl1.OnAfterDraw += AxMapControl1_OnAfterDraw;
                metroChoice.SelectedIndexChanged += metroChoice_SelectedIndexChanged;
            }
        }

        /// <summary>
        /// 地图绘制完成后的处理事件
        /// </summary>
        private void AxMapControl1_OnAfterDraw(object sender, IMapControlEvents2_OnAfterDrawEvent e)
        {
            if (_mapControl.Map == null) return;

            int currentMapLayerCount = _mapControl.Map.LayerCount;
            if (currentMapLayerCount != _layerCount) // 检查图层数量是否发生变化
            {
                _layerCount = currentMapLayerCount;
                PopulatePointNames(); // 重新填充站点名称下拉框
                _currentMetroGraph = null; // 清除缓存的网络图
                shortestPast.Enabled = HasEnoughDataForAnalysis(); // 检查是否可以进行分析
            }
        }

        /// <summary>
        /// 检查是否有足够的数据进行路径分析
        /// </summary>
        private bool HasEnoughDataForAnalysis()
        {
            if (_mapControl.Map == null || _mapControl.Map.LayerCount < 1) return false;

            bool hasPointLayer = false; // 是否有站点图层
            bool hasLineLayer = false;  // 是否有线路图层

            for (int i = 0; i < _mapControl.Map.LayerCount; i++)
            {
                ILayer layer = _mapControl.Map.get_Layer(i);
                if (layer is IFeatureLayer featureLayer && featureLayer.Valid && featureLayer.FeatureClass != null)
                {
                    if (featureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
                        hasPointLayer = true;
                    else if (featureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
                        hasLineLayer = true;
                }
                if (hasPointLayer && hasLineLayer) return true;
            }
            return hasPointLayer && hasLineLayer;
        }

        // 菜单事件处理
        private void btnconfig_Click(object sender, EventArgs e) { }
        private void exit_Click(object sender, EventArgs e) { Application.Exit(); }
        private void about_Click(object sender, EventArgs e)
        {
            MessageBox.Show("本程序由李晨可、刘镇嘉、孙雍贺、叶嘉玺、张云山编写。", "关于");
        }

        /// <summary>
        /// 更新下拉框内容
        /// </summary>
        private void UpdateComboBoxes(HashSet<string> namesToAdd)
        {
            var existingStartItems = new HashSet<string>(cboStart.Items.Cast<string>());
            var existingDeterItems = new HashSet<string>(cboDeter.Items.Cast<string>());

            foreach (string name in namesToAdd.OrderBy(n => n))
            {
                if (!existingStartItems.Contains(name))
                {
                    cboStart.Items.Add(name);
                    existingStartItems.Add(name);
                }
                if (!existingDeterItems.Contains(name))
                {
                    cboDeter.Items.Add(name);
                    existingDeterItems.Add(name);
                }
            }
            if (cboStart.Items.Count > 0 && !cboStart.Sorted) cboStart.Sorted = true;
            if (cboDeter.Items.Count > 0 && !cboDeter.Sorted) cboDeter.Sorted = true;
        }

        /// <summary>
        /// 从所有站点图层中提取站点名称并填充下拉框
        /// </summary>
        private void PopulatePointNames()
        {
            if (_mapControl.Map == null) return;

            HashSet<string> allPointNames = new HashSet<string>();

            for (int i = 0; i < _mapControl.Map.LayerCount; i++)
            {
                ILayer layer = _mapControl.Map.get_Layer(i);
                if (layer is IFeatureLayer featureLayer && featureLayer.Valid)
                {
                    IFeatureClass featureClass = featureLayer.FeatureClass;
                    if (featureClass != null && featureClass.ShapeType == esriGeometryType.esriGeometryPoint)
                    {
                        IQueryFilter queryFilter = new QueryFilterClass();
                        queryFilter.WhereClause = "";
                        IFeatureCursor featureCursor = null;
                        IFeature feature = null;
                        try
                        {
                            featureCursor = featureClass.Search(queryFilter, true);
                            int nameFieldIndex = featureClass.FindField("NAME");
                            if (nameFieldIndex != -1)
                            {
                                while ((feature = featureCursor.NextFeature()) != null)
                                {
                                    object nameValue = feature.get_Value(nameFieldIndex);
                                    if (nameValue != null && !string.IsNullOrEmpty(nameValue.ToString()))
                                    {
                                        allPointNames.Add(nameValue.ToString());
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show($"从图层 '{featureLayer.Name}' 读取站点名称时出错: {ex.Message}", "错误");
                        }
                        finally
                        {
                            if (featureCursor != null) Marshal.ReleaseComObject(featureCursor);
                        }
                    }
                }
            }

            // 清空并重新填充下拉框
            cboStart.Items.Clear();
            cboDeter.Items.Clear();
            cboStart.Sorted = false;
            cboDeter.Sorted = false;

            UpdateComboBoxes(allPointNames);

            if (cboStart.Items.Count == 0) cboStart.Text = "请选择起始点";
            if (cboDeter.Items.Count == 0) cboDeter.Text = "请选择结束点";
        }

        // 窗体关闭事件
        private void Form1_FormClosed(object sender, FormClosedEventArgs e) { }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("退出程序？", "提示", MessageBoxButtons.OKCancel);
            if (result == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
        }

        /// <summary>
        /// 清除地图内容
        /// </summary>
        private void clear_Click(object sender, EventArgs e)
        {
            if (_mapControl != null && _mapControl.Map != null)
            {
                // 清除所有图层
                _mapControl.Map.ClearLayers();

                // 清除图形容器中的所有元素（如站名标注）
                IGraphicsContainer graphicsContainer = _mapControl.ActiveView as IGraphicsContainer;
                if (graphicsContainer != null)
                {
                    graphicsContainer.DeleteAllElements();
                }

                // 刷新地图
                _mapControl.ActiveView.Refresh();
            }

            // 重置界面状态
            cboStart.Items.Clear();
            cboStart.Text = "请选择起始点";
            cboDeter.Items.Clear();
            cboDeter.Text = "请选择结束点";
            Result.Text = "换乘路线分析：";
            shortestPast.Enabled = false;
            _currentMetroGraph = null;
            _layerCount = 0;
        }

        /// <summary>
        /// 加载北京地铁GDB数据
        /// </summary>
        private void LoadBeijingGDB()
        {
            IWorkspace workspace = null;
            IWorkspaceFactory workspaceFactory = null;
            IEnumDataset enumDataset = null;
            IFeatureWorkspace featureWorkspace = null;
            try
            {
                string gdbFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resource", "BJ.gdb");
                if (!Directory.Exists(gdbFilePath))
                {
                    MessageBox.Show($"找不到GDB文件夹：{gdbFilePath}", "错误"); return;
                }

                workspaceFactory = new FileGDBWorkspaceFactoryClass();
                workspace = workspaceFactory.OpenFromFile(gdbFilePath, 0);
                featureWorkspace = (IFeatureWorkspace)workspace;

                enumDataset = workspace.Datasets[esriDatasetType.esriDTFeatureClass];
                enumDataset.Reset();
                IDataset dataset;

                while ((dataset = enumDataset.Next()) != null)
                {
                    IFeatureClass featureClass = null;
                    IFeatureLayer featureLayer = null;
                    try
                    {
                        if (dataset is IFeatureClass)
                        {
                            featureClass = (IFeatureClass)dataset;
                        }
                        else if (dataset.Type == esriDatasetType.esriDTFeatureClass)
                        {
                            featureClass = featureWorkspace.OpenFeatureClass(dataset.Name);
                        }

                        if (featureClass == null) continue;

                        featureLayer = new FeatureLayerClass();
                        featureLayer.FeatureClass = featureClass;
                        featureLayer.Name = featureClass.AliasName;
                        _mapControl.Map.AddLayer(featureLayer);
                    }
                    catch (Exception exLayer)
                    {
                        MessageBox.Show($"加载图层 {dataset?.Name} 失败: {exLayer.Message}", "图层加载错误");
                    }
                }
                _mapControl.Refresh();
                MessageBox.Show("加载成功！", "加载提示");
                _currentMetroGraph = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载GDB失败：{ex.Message}", "错误");
            }
            finally
            {
                if (enumDataset != null) Marshal.ReleaseComObject(enumDataset);
                if (workspace != null) Marshal.ReleaseComObject(workspace);
                if (workspaceFactory != null) Marshal.ReleaseComObject(workspaceFactory);
            }
        }

        private void metroChoice_SelectedIndexChanged(object sender, EventArgs e) { }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!DesignMode)
            {
                _mapControl = (IMapControl4)axMapControl1.Object;
                if (_mapControl != null && _mapControl.Map != null)
                {
                    _layerCount = _mapControl.Map.LayerCount;
                    axMapControl1.OnAfterDraw += AxMapControl1_OnAfterDraw;
                    metroChoice.SelectedIndexChanged += metroChoice_SelectedIndexChanged;
                }
                else
                {
                    MessageBox.Show("MapControl 或 Map 未初始化！", "错误");
                }
            }
        }

        /// <summary>
        /// 城市选择下拉框关闭事件，加载对应城市的地铁数据
        /// </summary>
        private void metroChoice_DropDownClosed(object sender, EventArgs e)
        {
            if (metroChoice.SelectedItem == null) return;
            string selectedCity = metroChoice.SelectedItem.ToString();

            // 清除现有数据
            if (_mapControl.Map != null) _mapControl.Map.ClearLayers();
            _currentMetroGraph = null;
            PopulatePointNames();
            _mapControl.Refresh();

            // 根据选择的城市加载数据
            if (selectedCity == "北京市")
            {
                LoadBeijingGDB();
            }
            else if (selectedCity == "天津市" || selectedCity == "南通市" || selectedCity == "青岛市")
            {
                MessageBox.Show("功能尚在开发中！", "提示");
                shortestPast.Enabled = false;
            }
            else if (selectedCity == "唐山市")
            {
                MessageBox.Show("唐山市没有地铁！", "提示");
                shortestPast.Enabled = false;
            }
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { }

        /// <summary>
        /// 最短路径分析主要处理逻辑
        /// </summary>
        private void shortestPast_Click(object sender, EventArgs e)
        {
            // 暂时禁用下拉框
            cboStart.Enabled = false;
            cboDeter.Enabled = false;

            // 验证输入
            if (cboStart.SelectedItem == null || cboDeter.SelectedItem == null)
            {
                MessageBox.Show("请选择起始点和结束点。", "提示");
                return;
            }

            string startStationName = cboStart.SelectedItem.ToString();
            string endStationName = cboDeter.SelectedItem.ToString();

            if (startStationName == endStationName)
            {
                MessageBox.Show("起始点和结束点不能相同。", "提示");
                return;
            }

            // 清除之前的图形元素
            if (_mapControl.ActiveView != null && _mapControl.ActiveView.GraphicsContainer != null)
            {
                _mapControl.ActiveView.GraphicsContainer.DeleteAllElements();
                _mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }

            Result.Text = "换乘路线分析：";
            Result.Enabled = true;

            try
            {
                this.Cursor = Cursors.WaitCursor;

                // 构建地铁网络图（如果还未构建）
                if (_currentMetroGraph == null)
                {
                    _currentMetroGraph = BuildMetroGraphFromMapLayers();
                }

                if (_currentMetroGraph == null || _currentMetroGraph.Nodes.Count == 0)
                {
                    MessageBox.Show("无法构建地铁网络图。\n请确保已加载正确的站点和线路图层。", "错误");
                    return;
                }

                // 设置优化模式（这里默认使用最短距离模式）
                DijkstraSolver.OptimizationMode selectedMode = DijkstraSolver.OptimizationMode.ShortestDistance;

                // 执行路径搜索
                DijkstraSolver solver = new DijkstraSolver(_currentMetroGraph, selectedMode);
                DijkstraSolver.PathFindingResult pathResult = solver.FindShortestPath(startStationName, endStationName);

                if (pathResult != null && pathResult.Nodes != null && pathResult.Nodes.Count > 0)
                {
                    // 在地图上高亮显示路径
                    HighlightRouteFromNodes(pathResult.Nodes);
                    // 在结果框中显示换乘信息
                    DisplayTransferInfoFromNodes(pathResult.Nodes, startStationName, endStationName, selectedMode, pathResult.TotalCostValue);
                    Result.Enabled = true;
                }
                else
                {
                    MessageBox.Show($"未能找到从 {startStationName} 到 {endStationName} 的路径。", "路径分析结果");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"执行路径分析时发生错误: {ex.Message}\n详细信息: {ex.StackTrace}", "严重错误");
            }
            finally
            {
                this.Cursor = Cursors.Default;
                if (_mapControl.ActiveView != null)
                {
                    _mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGeography, null, null);
                }
            }
        }

        /// <summary>
        /// 从地图图层构建地铁网络图
        /// </summary>
        private MetroGraph BuildMetroGraphFromMapLayers()
        {
            MetroGraph graph = new MetroGraph();
            if (_mapControl.Map == null || _mapControl.Map.LayerCount == 0) return null;

            // 查找站点和线路图层
            IFeatureClass stationFc = null;
            List<IFeatureClass> lineFcs = new List<IFeatureClass>();
            string stationLayerNamePattern = "站点";
            string lineLayerNamePattern = "线路";

            for (int i = 0; i < _mapControl.Map.LayerCount; i++)
            {
                ILayer layer = _mapControl.Map.get_Layer(i);
                if (layer is IFeatureLayer featLayer && featLayer.Valid && featLayer.FeatureClass != null)
                {
                    if (featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)
                    {
                        if (stationFc == null && (featLayer.Name.Contains(stationLayerNamePattern) || string.IsNullOrEmpty(stationLayerNamePattern)))
                            stationFc = featLayer.FeatureClass;
                        else if (stationFc == null && i == 0)
                            stationFc = featLayer.FeatureClass;
                    }
                    else if (featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline)
                    {
                        if (featLayer.Name.Contains(lineLayerNamePattern) || string.IsNullOrEmpty(lineLayerNamePattern))
                            lineFcs.Add(featLayer.FeatureClass);
                        else
                            lineFcs.Add(featLayer.FeatureClass);
                    }
                }
            }

            if (stationFc == null) { MessageBox.Show($"未找到合适的站点图层。", "错误"); return null; }
            if (!lineFcs.Any()) { MessageBox.Show($"未找到合适的线路图层。", "错误"); return null; }

            int stationNameFieldIndex = stationFc.FindField("NAME");
            if (stationNameFieldIndex == -1) { MessageBox.Show("站点图层缺少'NAME'字段。", "错误"); return null; }

            // 添加站点节点
            IFeatureCursor stationCursor = null;
            IFeature stationFeature = null;
            try
            {
                stationCursor = stationFc.Search(null, true);
                while ((stationFeature = stationCursor.NextFeature()) != null)
                {
                    string name = stationFeature.get_Value(stationNameFieldIndex)?.ToString();
                    if (!string.IsNullOrEmpty(name))
                    {
                        IPoint stationGeom = stationFeature.ShapeCopy as IPoint;
                        if (stationGeom != null && stationGeom.SpatialReference == null && _mapControl.Map.SpatialReference != null)
                        {
                            stationGeom.SpatialReference = _mapControl.Map.SpatialReference;
                        }
                        graph.AddNode(new StationNode(name, name, stationGeom));
                    }
                }
            }
            finally { if (stationCursor != null) Marshal.ReleaseComObject(stationCursor); }

            // 添加线路边
            foreach (IFeatureClass lineFc in lineFcs)
            {
                int lineNameFieldIndex = lineFc.FindField("Layer");
                if (lineNameFieldIndex == -1) lineNameFieldIndex = lineFc.FindField("LINE_NAME");
                if (lineNameFieldIndex == -1) lineNameFieldIndex = lineFc.FindField("线路名");

                IFeatureCursor lineCursor = null;
                IFeature lineFeature = null;
                try
                {
                    lineCursor = lineFc.Search(null, true);
                    while ((lineFeature = lineCursor.NextFeature()) != null)
                    {
                        IPolyline polyline = lineFeature.Shape as IPolyline;
                        if (polyline == null || polyline.IsEmpty) continue;

                        if (polyline.SpatialReference == null && _mapControl.Map.SpatialReference != null)
                        {
                            polyline.SpatialReference = _mapControl.Map.SpatialReference;
                        }

                        double distanceInMeters = polyline.Length;
                        if (distanceInMeters <= 0) continue;

                        // 计算距离成本和时间成本
                        double distanceCost = distanceInMeters;
                        double baseTravelTimeSeconds = distanceInMeters * 3.6 / 35.0; // 基于35km/h速度

                        string lineNameStr = "未知线路";
                        if (lineNameFieldIndex != -1 && lineFeature.get_Value(lineNameFieldIndex) != DBNull.Value)
                            lineNameStr = lineFeature.get_Value(lineNameFieldIndex)?.ToString() ?? "未知线路";

                        // 设置匹配容差
                        double snappingTolerance;
                        if (_mapControl.Map.SpatialReference is IProjectedCoordinateSystem)
                        {
                            snappingTolerance = 100.0;
                        }
                        else
                        {
                            snappingTolerance = 0.005;
                        }

                        // 查找线路两端对应的站点
                        string fromStationId = FindStationNameByPointProximity(graph, polyline.FromPoint, snappingTolerance);
                        string toStationId = FindStationNameByPointProximity(graph, polyline.ToPoint, snappingTolerance);

                        if (fromStationId != null && toStationId != null && fromStationId != toStationId)
                        {
                            graph.AddEdge(fromStationId, toStationId, distanceCost, baseTravelTimeSeconds, lineNameStr);
                        }
                    }
                }
                catch (Exception exFc)
                {
                    MessageBox.Show($"处理线路图层 {((IDataset)lineFc).Name} 时出错: {exFc.Message}", "错误");
                }
                finally { if (lineCursor != null) Marshal.ReleaseComObject(lineCursor); }
            }
            return graph;
        }

        /// <summary>
        /// 根据点的位置查找最近的站点
        /// </summary>
        private string FindStationNameByPointProximity(MetroGraph graph, IPoint pointToFind, double tolerance)
        {
            if (pointToFind == null || graph == null || pointToFind.IsEmpty) return null;

            if (pointToFind.SpatialReference == null && _mapControl.Map.SpatialReference != null)
            {
                pointToFind.SpatialReference = _mapControl.Map.SpatialReference;
            }

            string closestStationId = null;
            double minDistance = double.MaxValue;

            IProximityOperator proximityOperator = (IProximityOperator)pointToFind;

            foreach (var node in graph.Nodes.Values)
            {
                if (node.Geometry != null && !node.Geometry.IsEmpty)
                {
                    IGeometry nodeGeom = (IGeometry)node.Geometry;

                    if (nodeGeom.SpatialReference == null && _mapControl.Map.SpatialReference != null)
                    {
                        nodeGeom.SpatialReference = _mapControl.Map.SpatialReference;
                    }

                    if (pointToFind.SpatialReference != null && nodeGeom.SpatialReference != null)
                    {
                        if (!pointToFind.SpatialReference.FactoryCode.Equals(nodeGeom.SpatialReference.FactoryCode))
                        {
                            try
                            {
                                ESRI.ArcGIS.esriSystem.IClone clonableOriginalGeom = (ESRI.ArcGIS.esriSystem.IClone)nodeGeom;
                                IGeometry tempGeom = (IGeometry)clonableOriginalGeom.Clone();
                                tempGeom.Project(pointToFind.SpatialReference);
                                double distance = proximityOperator.ReturnDistance(tempGeom);
                                if (distance <= tolerance && distance < minDistance)
                                {
                                    minDistance = distance;
                                    closestStationId = node.Id;
                                }
                                if (tempGeom != null) Marshal.ReleaseComObject(tempGeom);
                            }
                            catch (Exception)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            double distance = proximityOperator.ReturnDistance(nodeGeom);
                            if (distance <= tolerance && distance < minDistance)
                            {
                                minDistance = distance;
                                closestStationId = node.Id;
                            }
                        }
                    }
                }
            }
            return closestStationId;
        }

        /// <summary>
        /// 在地图上高亮显示路径并标注站点名称
        /// </summary>
        private void HighlightRouteFromNodes(List<StationNode> pathNodes)
        {
            if (pathNodes == null || pathNodes.Count < 2)
            {
                MessageBox.Show("路径无效，无法显示站名", "错误");
                return;
            }

            IActiveView activeView = _mapControl.ActiveView;
            if (activeView == null)
            {
                MessageBox.Show("地图视图未初始化", "错误");
                return;
            }

            IGraphicsContainer graphicsContainer = activeView.GraphicsContainer;
            if (graphicsContainer == null)
            {
                MessageBox.Show("图形容器未初始化", "错误");
                return;
            }

            ISpatialReference mapSpatialReference = _mapControl.Map.SpatialReference;
            IEnvelope envelope = new EnvelopeClass();
            envelope.SpatialReference = mapSpatialReference;

            // 动态调整偏移量
            double xOffset = 0.0001;
            double yOffset = -0.0001;
            if (mapSpatialReference is IProjectedCoordinateSystem)
            {
                xOffset = 10.0;
                yOffset = -10.0;
            }

            string currentLineName = "未知线路";
            int stationsLabeled = 0;

            for (int i = 0; i < pathNodes.Count; i++)
            {
                StationNode currentNode = pathNodes[i];
                bool shouldLabel = false;
                string stationLabel = currentNode.Name;
                IColor textColor = new RgbColorClass { Red = 80, Green = 80, Blue = 240 }; // 默认蓝色

                // 确定是否需要标注以及使用什么颜色
                if (i == 0) // 起始站
                {
                    shouldLabel = true;
                    stationLabel += "(起点)";
                    textColor = new RgbColorClass { Red = 115, Green = 190, Blue = 40 }; // 绿色
                    if (pathNodes.Count > 1)
                    {
                        currentNode.EdgeLineNames.TryGetValue(pathNodes[1], out currentLineName);
                    }
                }
                else if (i == pathNodes.Count - 1) // 终点站
                {
                    shouldLabel = true;
                    stationLabel += "(终点)";
                    textColor = new RgbColorClass { Red = 200, Green = 37, Blue = 25 }; // 红色
                }
                else // 中间站点，检查是否需要换乘
                {
                    StationNode prevNode = pathNodes[i - 1];
                    StationNode nextNode = pathNodes[i + 1];
                    string traveledLineName = prevNode.EdgeLineNames.ContainsKey(currentNode) ? prevNode.EdgeLineNames[currentNode] : "未知线路";
                    string nextLineName = currentNode.EdgeLineNames.ContainsKey(nextNode) ? currentNode.EdgeLineNames[nextNode] : "未知线路";

                    if (currentLineName != nextLineName || (currentLineName == "未知线路" && traveledLineName != nextLineName && traveledLineName != "未知线路"))
                    {
                        shouldLabel = true;
                        textColor = new RgbColorClass { Red = 0, Green = 0, Blue = 255 }; // 蓝色
                        currentLineName = nextLineName;
                    }
                }

                if (shouldLabel && currentNode.Geometry != null && !currentNode.Geometry.IsEmpty)
                {
                    IPoint point = null;
                    try
                    {
                        IClone clonableGeom = (IClone)currentNode.Geometry;
                        point = (IPoint)clonableGeom.Clone();

                        if (point.SpatialReference == null)
                        {
                            if (mapSpatialReference != null)
                            {
                                point.SpatialReference = mapSpatialReference;
                            }
                            else
                            {
                                continue;
                            }
                        }

                        if (mapSpatialReference != null && point.SpatialReference.FactoryCode != mapSpatialReference.FactoryCode)
                        {
                            point.Project(mapSpatialReference);
                        }

                        if (!point.IsEmpty)
                        {
                            IPoint offsetPoint = new PointClass();
                            offsetPoint.PutCoords(point.X + xOffset, point.Y + yOffset);
                            offsetPoint.SpatialReference = point.SpatialReference;
                            point = offsetPoint;
                        }

                        // 设置文本符号样式
                        ITextSymbol textSymbol = new TextSymbolClass();
                        textSymbol.Size = 16;
                        textSymbol.Color = textColor; // 使用确定的颜色
                        IFontDisp font = new StdFont { Name = "KaiTi" } as IFontDisp;
                        font.Size = (decimal)textSymbol.Size;
                        textSymbol.Font = font;
                        textSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;
                        textSymbol.VerticalAlignment = esriTextVerticalAlignment.esriTVABottom;

                        ITextElement textElement = new TextElementClass();
                        textElement.Text = stationLabel; // 使用包含标注的站名
                        textElement.Symbol = textSymbol;
                        ((IElement)textElement).Geometry = point;

                        graphicsContainer.AddElement((IElement)textElement, 0);
                        stationsLabeled++;

                        envelope.Union(point.Envelope);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"标注站名 '{currentNode.Name}' 失败: {ex.Message}");
                    }
                    finally
                    {
                        if (point != null) Marshal.ReleaseComObject(point);
                    }
                }
            }

            try
            {
                if (!envelope.IsEmpty)
                {
                    envelope.Expand(1.2, 1.2, true);
                    activeView.Extent = envelope;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"缩放失败: {ex.Message}");
            }

            activeView.Refresh();
            System.Diagnostics.Debug.WriteLine($"已标注 {stationsLabeled} 个站名");
        }

        /// <summary>
        /// 在结果文本框中显示详细的换乘信息
        /// </summary>
        private void DisplayTransferInfoFromNodes(List<StationNode> pathNodes, string startStationName, string endStationName,
                                              DijkstraSolver.OptimizationMode mode, double optimizedTotalCost)
        {
            Result.Text = "换乘路线分析：\n";
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"从 [{startStationName}] 到 [{endStationName}]：");

            if (pathNodes == null || pathNodes.Count <= 1)
            {
                sb.AppendLine(pathNodes != null && pathNodes.Count == 1 ? $"您已在目的地：[{pathNodes[0].Name}]" : "未能找到有效路径或路径信息不足。");
                sb.AppendLine("\n未发生有效行程，无法计算票价。");
                sb.AppendLine($"总行程时间：0.00 分钟");
                Result.Text += sb.ToString();
                return;
            }

            // 显示路径详情
            string currentLineNameForSegmentOutput = "未知线路";
            for (int i = 0; i < pathNodes.Count; i++)
            {
                StationNode currentNode = pathNodes[i];
                if (i == 0)
                {
                    sb.AppendLine($"从 [{currentNode.Name}] 出发");
                    if (pathNodes.Count > 1)
                    {
                        StationNode nextNode = pathNodes[1];
                        if (currentNode.EdgeLineNames.TryGetValue(nextNode, out string lineName))
                        { currentLineNameForSegmentOutput = lineName; }
                        sb.AppendLine($"乘坐 [{currentLineNameForSegmentOutput}]");
                    }
                }
                else
                {
                    StationNode prevNode = pathNodes[i - 1];
                    string traveledLineName = "未知线路";
                    if (prevNode.EdgeLineNames.TryGetValue(currentNode, out string ln))
                    { traveledLineName = ln; }

                    if (i < pathNodes.Count - 1)
                    {
                        StationNode nextNode = pathNodes[i + 1];
                        string nextSegmentLineName = "未知线路";
                        if (currentNode.EdgeLineNames.TryGetValue(nextNode, out string nextLn))
                        { nextSegmentLineName = nextLn; }

                        if (currentLineNameForSegmentOutput != nextSegmentLineName && !(string.IsNullOrEmpty(currentLineNameForSegmentOutput) && string.IsNullOrEmpty(nextSegmentLineName)))
                        {
                            sb.AppendLine($"-> 到达 [{currentNode.Name}]");
                            sb.AppendLine($"(乘坐 {traveledLineName})");
                            sb.AppendLine($"== 在 [{currentNode.Name}] 换乘 [{nextSegmentLineName}]");
                            currentLineNameForSegmentOutput = nextSegmentLineName;
                        }
                        else
                        {
                            sb.AppendLine($"-> 途经 [{currentNode.Name}] (继续乘坐 {traveledLineName})");
                            if (string.IsNullOrEmpty(currentLineNameForSegmentOutput) && !string.IsNullOrEmpty(traveledLineName))
                            { currentLineNameForSegmentOutput = traveledLineName; }
                        }
                    }
                    else
                    {
                        sb.AppendLine($"-> 到达终点站 [{currentNode.Name}]");
                        sb.AppendLine($"(乘坐 {traveledLineName})");
                    }
                }
            }

            // 票价计算
            int stationsTraveled = pathNodes.Count - 1;
            int fare = 0;
            if (stationsTraveled <= 0) fare = 0;
            else if (stationsTraveled <= 5) fare = 3;
            else if (stationsTraveled <= 10) fare = 4;
            else if (stationsTraveled <= 15) fare = 5;
            else if (stationsTraveled <= 20) fare = 6;
            else fare = 7;

            sb.AppendLine();
            if (stationsTraveled > 0)
            {
                sb.AppendLine($"共经过 {stationsTraveled} 站。");
                sb.AppendLine($"预计票价：{fare}元");
            }
            else
            {
                sb.AppendLine("未发生有效行程，无法计算票价。");
            }

            // 计算总行程时间（简化版本）
            double totalTimeMinutes = 0;

            if (stationsTraveled > 0)
            {
                // 1. 停站时间：每站2.8分钟
                totalTimeMinutes += stationsTraveled * 2.8;

                // 2. 计算换乘次数和换乘时间
                int transferCount = 0;
                string currentLine = "未知线路";

                for (int i = 0; i < pathNodes.Count - 1; i++)
                {
                    StationNode currentNode = pathNodes[i];
                    StationNode nextNode = pathNodes[i + 1];

                    if (currentNode.EdgeLineNames.TryGetValue(nextNode, out string segmentLine))
                    {
                        if (i == 0)
                        {
                            currentLine = segmentLine; // 设置起始线路
                        }
                        else if (currentLine != segmentLine && currentLine != "未知线路" && segmentLine != "未知线路")
                        {
                            transferCount++;
                            currentLine = segmentLine; // 更新当前线路
                        }
                    }
                }

                // 每次换乘增加5分钟
                totalTimeMinutes += transferCount * 5.0;
            }

            sb.AppendLine($"总行程时间：{totalTimeMinutes:F2} 分钟");

            Result.Text += sb.ToString();
            Result.Enabled = true;
        }

        private void Result_TextChanged(object sender, EventArgs e) { }

        /// <summary>
        /// 清除地图上的图形标注
        /// </summary>
        private void btnClear_Click(object sender, EventArgs e)
        {
            if (_mapControl != null && _mapControl.ActiveView != null)
            {
                IGraphicsContainer graphicsContainer = _mapControl.ActiveView as IGraphicsContainer;
                if (graphicsContainer != null)
                {
                    graphicsContainer.DeleteAllElements();
                }
                _mapControl.ActiveView.Refresh();
            }

            // 重置界面状态
            cboStart.Enabled = true;
            cboDeter.Enabled = true;
            cboStart.Text = "请选择起始点";
            cboDeter.Text = "请选择结束点";
            Result.Text = "换乘路线分析：";

            shortestPast.Enabled = HasEnoughDataForAnalysis();
        }
    } // End of Form1 class

    /// <summary>
    /// 边的成本信息结构，包含距离和时间成本
    /// </summary>
    public struct EdgeCostInfo
    {
        public double Distance { get; set; } // 几何距离 (米)
        public double BaseTravelTime { get; set; } // 行驶时间 (秒)

        public EdgeCostInfo(double distance, double baseTravelTime)
        {
            Distance = distance;
            BaseTravelTime = baseTravelTime;
        }
    }

    /// <summary>
    /// 地铁站点节点类
    /// </summary>
    public class StationNode
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public IPoint Geometry { get; set; }
        public Dictionary<StationNode, EdgeCostInfo> EdgeCostsToNeighbors { get; set; } // 邻接节点及其成本
        public Dictionary<StationNode, string> EdgeLineNames { get; set; } // 邻接节点及其线路名

        public StationNode(string id, string name, IPoint geometry = null)
        {
            Id = id;
            Name = name;
            Geometry = geometry;
            EdgeCostsToNeighbors = new Dictionary<StationNode, EdgeCostInfo>();
            EdgeLineNames = new Dictionary<StationNode, string>();
        }
    }

    /// <summary>
    /// 地铁网络图类
    /// </summary>
    public class MetroGraph
    {
        public Dictionary<string, StationNode> Nodes { get; set; }

        public MetroGraph()
        {
            Nodes = new Dictionary<string, StationNode>();
        }

        public void AddNode(StationNode node)
        {
            if (!Nodes.ContainsKey(node.Id))
            {
                Nodes.Add(node.Id, node);
            }
        }

        public StationNode GetNode(string nodeId)
        {
            Nodes.TryGetValue(nodeId, out StationNode node);
            return node;
        }

        /// <summary>
        /// 添加双向边到图中
        /// </summary>
        public void AddEdge(string fromNodeId, string toNodeId, double distanceCost, double baseTravelTimeCost, string lineName = "未知线路")
        {
            if (Nodes.ContainsKey(fromNodeId) && Nodes.ContainsKey(toNodeId))
            {
                StationNode fromNode = Nodes[fromNodeId];
                StationNode toNode = Nodes[toNodeId];
                EdgeCostInfo cost = new EdgeCostInfo(distanceCost, baseTravelTimeCost);

                if (!fromNode.EdgeCostsToNeighbors.ContainsKey(toNode))
                {
                    fromNode.EdgeCostsToNeighbors.Add(toNode, cost);
                    fromNode.EdgeLineNames.Add(toNode, lineName);
                }
                if (!toNode.EdgeCostsToNeighbors.ContainsKey(fromNode)) // 无向图，添加反向边
                {
                    toNode.EdgeCostsToNeighbors.Add(fromNode, cost);
                    toNode.EdgeLineNames.Add(fromNode, lineName);
                }
            }
        }
    }

    /// <summary>
    /// 使用Dijkstra算法求解最短路径的求解器
    /// </summary>
    public class DijkstraSolver
    {
        private MetroGraph _graph;
        private OptimizationMode _mode;

        // 时间惩罚常数
        public const double TRANSFER_PENALTY_SECONDS = 5.0 * 60.0; // 换乘惩罚时间
        public const double STATION_STOP_TIME_SECONDS = 2.8 * 60.0; // 停站时间

        public enum OptimizationMode
        {
            ShortestDistance, // 最短距离模式
            ShortestTime      // 最短时间模式（当前简化实现）
        }

        public DijkstraSolver(MetroGraph graph, OptimizationMode mode)
        {
            _graph = graph;
            _mode = mode;
        }

        /// <summary>
        /// 路径查找结果类
        /// </summary>
        public class PathFindingResult
        {
            public List<StationNode> Nodes { get; set; }
            public double TotalCostValue { get; set; }
        }

        /// <summary>
        /// 查找两点间最短路径
        /// </summary>
        public PathFindingResult FindShortestPath(string startNodeId, string endNodeId)
        {
            StationNode startNode = _graph.GetNode(startNodeId);
            StationNode endNode = _graph.GetNode(endNodeId);

            if (startNode == null || endNode == null) return null;

            var distances = new Dictionary<StationNode, double>();
            var previousNodes = new Dictionary<StationNode, StationNode>();
            var priorityQueue = new SortedSet<StationNode>(Comparer<StationNode>.Create((a, b) =>
            {
                double distA = distances.ContainsKey(a) ? distances[a] : double.PositiveInfinity;
                double distB = distances.ContainsKey(b) ? distances[b] : double.PositiveInfinity;
                int distanceCompare = distA.CompareTo(distB);
                if (distanceCompare == 0) return a.Id.CompareTo(b.Id);
                return distanceCompare;
            }));

            // 初始化距离
            foreach (var node in _graph.Nodes.Values)
            {
                distances[node] = double.PositiveInfinity;
                previousNodes[node] = null;
            }

            distances[startNode] = 0;
            priorityQueue.Add(startNode);

            while (priorityQueue.Any())
            {
                StationNode currentNode = priorityQueue.Min;
                priorityQueue.Remove(currentNode);

                if (currentNode == endNode)
                {
                    return new PathFindingResult
                    {
                        Nodes = ReconstructPath(previousNodes, endNode),
                        TotalCostValue = distances[endNode]
                    };
                }

                if (double.IsPositiveInfinity(distances[currentNode])) break;

                foreach (var neighborEntry in currentNode.EdgeCostsToNeighbors)
                {
                    StationNode neighbor = neighborEntry.Key;
                    EdgeCostInfo costInfoToNeighbor = neighborEntry.Value;

                    double effectiveWeight;

                    // 根据优化模式选择成本计算方式
                    if (_mode == OptimizationMode.ShortestDistance)
                    {
                        effectiveWeight = costInfoToNeighbor.Distance; // 使用距离成本
                    }
                    else // ShortestTime 模式（简化版本，仅使用距离）
                    {
                        effectiveWeight = costInfoToNeighbor.Distance; // 当前简化为距离模式
                    }

                    double distanceThroughCurrent = distances[currentNode] + effectiveWeight;

                    if (distanceThroughCurrent < distances[neighbor])
                    {
                        if (priorityQueue.Contains(neighbor))
                        {
                            priorityQueue.Remove(neighbor);
                        }
                        distances[neighbor] = distanceThroughCurrent;
                        previousNodes[neighbor] = currentNode;
                        priorityQueue.Add(neighbor);
                    }
                }
            }
            return null; // 未找到路径
        }

        /// <summary>
        /// 重构路径
        /// </summary>
        private List<StationNode> ReconstructPath(Dictionary<StationNode, StationNode> previousNodes, StationNode endNode)
        {
            var path = new List<StationNode>();
            StationNode currentNode = endNode;
            while (currentNode != null)
            {
                path.Add(currentNode);
                if (!previousNodes.TryGetValue(currentNode, out currentNode))
                {
                    break;
                }
            }
            path.Reverse();
            return path;
        }
    }
} // End of namespace BJMetro